Tiny Hexer Script: Commands
This page shows all available Tiny Hexer Script commands. Note: As of
version 1.6.0.2 of Tiny Hexer most functions
can be used like commands, i. e. functions which have no equally named
command counterpart can be used as first keyword in a script line (in this
case the function's result is discarded).
CALL target [,
param1, param2...]
Parameters:
target: the name of a
label or
local label in the current
script
param1/2...: optional
expressions that are pushed to the stack
more...
less...
CALL continues script execution at the position marked with the
label target after storing the current
command position internally. The RETURN or ENDLOCAL commands are used
to finish a LABEL or LOCAL subroutine, respectively. After calling a
subroutine, script execution continues at the command following the
CALL command.
The CALL command can have optional parameters that are pushed to the
stack. The subroutine can retrieve those parameters using the POP
command. (Note: Because the stack is a LIFO, the first POP in a
subroutine returns the last parameter, the second POP returns the last
but one parameter...). The called sub block can retrieve the number of
parameters pushed to the stack by reading the ARGC special variable.
Sample:
VAR t1 TEXT, t2 TEXT
= pushes 'first', than 'second' to the stack and calls the label concat
CALL concat, "first", "second"
= use the END command to avoid running into the subroutine again
END
LABEL concat
POP t1
= t1 now contains 'second' (the last parameter pushed to the stack)
POP t2
= t2 now contains 'first' (the last-but-one parameter pushed to the stack)
= displays the message 'second first' !!!
MSGBOX t1+" "+t2
= return from the subroutine to the command following the CALL
RETURN
|
|
CONCAT textvar,
textexpr
more...
less...
CONCAT concats the value of the text-type expression
textexpr to the text already stored in
the text-type variable textvar.
(Note: The CONCAT command is faster than the text-type '+'
operator.)
Sample:
VAR txt TEXT
= variable txt is set to the text 'foo'.
LET txt = "foo"
CONCAT txt, "bar"
= variable txt now contains the text 'foobar'.
COPYTAGS targetvar, sourcevar
Parameters:
targetvar and
sourcevar:
variable
names
more...
less...
DEF name
value
Parameters:
name: a valid identifier name
value: an expression
more...
less...
The DEF preprocessor statement is used to give certain
expressions or values descriptive names (similar to #define in the C
programming language). After assigning a descriptive name to a value,
this name stands for the value in the script.
Sample:
= tell Tiny Hexer Script to substitute all literal occurances of FOOBAR with 'Foo/Bar'
= and all literal occurances of MYMESSAGE with FOOBAR+'/whatsoever'
DEF FOOBAR 'Foo/Bar'
DEF MYMESSAGE FOOBAR + '/Whatsoever'
= show if it works
MSGBOX MYMESSAGE
DLLFUNC name
dllname [name funcname | index funcindex] [out outvartype] [in [@]invartype1 [,
[@]invartype2...]]
Parameters:
name: a valid identifier name
dllname: the name of a dynamic link
library containing the function
funcname: the optional name of the
function as it is called in the dll
funcindex: the optional index to the
function in the dll
outvartype,
invartype1,
invartype2...: optional
types of return value of the function and calling
parameters
more...
less...
The
DLLFUNC preprocessor statement is used to declare
stdcall functions stored in dynamic link libraries so they can
be executed from within Tiny Hexer Script. After declaring a function
from a dll, that function can be used like builtin functions in the
script using the
name
identifier.
dllname is the name of the dynamic
link library where the function resides.
The optional
name funcname or
index funcindex parameters are
used to define functions using different names in the script and the
library.
The optional
out outvartype
parameter tells the scripting engine the type of the data the function
returns. If no outvartype is specified, the engine assumes a
void function (that is a procedure) is to be called. The
following data types are supported:
TEXT (assumes LPCHAR),
CHAR,
BYTE,
WORD,
LONGWORD,
SIGBYTE,
SIGWORD and
SIGLONGWORD.
The optional
in invartype
parameters tell the scripting engine the type of the data to pass to
the function. If no invartypes are specified, the engine assumes that
no parameters should be passed to the function. The following data
types are supported:
TEXT,
WORD,
LONGWORD,
SINGLE,
SIGWORD,
SIGLONGWORD (by Value) and
TEXT,
CHAR,
BYTE,
WORD,
LONGWORD,
SIGQWORD,
DOUBLE,
SINGLE,
EXTENDED,
COMP,
SIGBYTE,
SIGWORD,
SIGLONGWORD (by Reference). To
distinguish by value parameters from by reference parameters, prefix
the by reference (pointer to the data) type declarations by an at sign
(
@).
Notes: To use data types unknown to Tiny Hexer Script (like
WinAPI structures), you can use "static" TEXT type parameters, that is
TEXT parameters with a specific length (usually the size of the
corresponding native structure). To define static TEXT parameters, tell
DLLFUNC the size of the structure by using the suffix
[size] to the TEXT type.
TEXT and CHAR parameters are always pushed as data pointers (by
reference) on the stack, the difference between byval and byref (the
latter one with
@ prefix) is that an unique amount of memory is
allocated for byref TEXT parameters.
Sample:
= use WINAPI functions to get and show the creation date/time of a selected file
= used WINAPI functions and structures:
= FindFirstFileA, FindCloseA, _WIN32_FIND_DATAA=TEXT[320] (size of this structure)
= FileTimeToLocalFileTime, FileTimeToSystemTime, _SYSTEMTIME=TEXT[16]
= GetTimeFormat, GetDateFormat
INCLUDE 'def.mps'
DLLFUNC FindFirstFile kernel32.dll name FindFirstFileA out LONGWORD in TEXT @TEXT[320]
DLLFUNC FindClose kernel32.dll out LONGWORD in LONGWORD
DLLFUNC FileTimeToLocalFileTime kernel32.dll in @SIGQWORD @SIGQWORD out LONGWORD
DLLFUNC FileTimeToSystemTime kernel32.dll out LONGWORD in @SIGQWORD @TEXT[16]
DLLFUNC GetTimeFormat kernel32.dll name GetTimeFormatA in DWORD DWORD TEXT[16] TEXT @TEXT SIGLONGWORD out SIGLONGWORD
DLLFUNC GetDateFormat kernel32.dll name GetDateFormatA in DWORD DWORD TEXT[16] TEXT @TEXT SIGLONGWORD out SIGLONGWORD
= select the file
VAR filename TEXT
filename = ASKOPENFILENAME("Select a file", "All Files (*.*)|*.*")
= try to get the file record
VAR findrec TEXT findhandle LONGWORD
findhandle = FINDFIRSTFILE(filename, @findrec)
IF findhandle == 0xffffffff
ERROR "Cannot find record for file "+filename
ENDIF
= close the FindFirstFile handle
FINDCLOSE(findhandle)
= get the "Creation time" _FILETIME record in the findrec structure (at position 5)
= dirty hack, but ths actually doesn't support structures ;-)
VAR filetime SIGQWORD:= _FILETIME is eight bytes in size, so we can use this variable type
findrec = TEXTCOPY(findrec, 5, 8)
filetime = TEXT2DATA(findrec, 0, -SIGQWORD_DATA)
= convert the filetime to a local filetime
VAR lfiletime SIGQWORD
IF (NOT FileTimeToLocalFileTime(@filetime, @lfiletime))
ERROR "Cannot convert file time to local filetime"
ENDIF
= convert the local filetime to a systemtime
VAR systemtime TEXT
IF (NOT FileTimeToSystemTime(@lfiletime, @systemtime))
ERROR "Cannot convert file time to systemtime"
ENDIF
LOCAL SystemTimeToString:= convert a _SYSTEMTIME to a date/time string
= params in systemtime (text[16]) out text
VAR in TEXT out TEXT temp TEXT nil NONE len SIGLONGWORD
POP in
temp = (CHAR(0)+CHAR(0)) * 128:= prepare a buffer
len = GetDateFormat(1 << 10 ,0, in, nil, @temp, 256)
IF (len == 0)
ERROR "Cannot convert date to string"
ENDIF
out = TEXTCHOP(TEXTCOPY(temp, 1, len))+' '
temp = (CHAR(0)+CHAR(0)) * 128:= prepare a buffer
len = GetTimeFormat(1 << 10 ,0, in, nil, @temp, 256)
IF (len == 0)
ERROR "Cannot convert time to string"
ENDIF
CONCAT out TEXTCHOP(TEXTCOPY(temp, 1, len))
RETURN out
ENDLOCAL
= convert the resulting _SYSTEMTIME to a text string
VAR timestring TEXT
timestring = #SystemTimeToString(systemtime)
= show result message
MSGBOX ("The file "+filename+" has been created on "+timestring)
|
|
END
more...
less...
The END command is used to stop script execution.
Sample:
VAR foo TEXT
END
= script execution is terminated at this position
LET foo = "bar"
= this command is never executed
ERROR textexpr
more...
less...
The ERROR command displays an error message textexpr and terminates script execution.
Sample:
VAR dividend LONGWORD divisor LONGWORD quotient LONGWORD
= enter divisor and dividend
LET dividend = LONGWORD(INPUT('Enter dividend:'))
LET divisor = LONGWORD(INPUT('Enter divisor:'))
IF ((divisor == 0) OR (dividend == 0))
= throw an errror message and terminate the script
ERROR "Neither dividend nor divisor must be zero!"
ELSE
LET quotient = dividend / divisor:= calculate quotient
= enable decimal number to text conversion
NUMBER_PREFIX=''
NUMBER_SUFFIX=''
NUMBER_RADIX=10
MSGBOX ("Result: "+TEXT(quotient))
ENDIF
ERRORHANDLER target | NONE
Parameters:
target: name of a
label in the current script (or the special value
NONE to disable error handling)
more...
less...
The ERRORHANDLER command allows to continue script execution at
the label target if an error occurs.
If the argument NONE is passed to the command, error handling is
disabled, so the script will be terminated on error (default).
(Note: if an error occurs at script execution and the label
target is called, error handling is
automatically disabled to avoid possible infinite recursions caused by
errors in the handler itself)
Sample:
INCLUDE 'def.mps'
VAR a LONGWORD, b LONGWORD
ERRORHANDLER errorlabel
= if an invalid numerical value is entered, the script is continued at
= the @errorlabel position
@@inputa:a= LONGWORD(INPUT('enter number 1'))
@@inputb:b= LONGWORD(INPUT('enter number 2'))
MSGBOX TEXT(a+b)
= force an error message
a = "this does not work, since a is a numerical variable!"
END
@@errorlabel
= exit if cancel command has been invoked
IF (ERRORNUMBER == ERROR_ABORT):END:ENDIF
ERRORHANDLER errorlabel:= reenable error handler
= if error occured in line 9 (@@inputa...), goto @@inputa,
= if error occured in line 10 (@@inputb...), goto @@inputb
IFGOTO ERRORLINE, 9, inputa, 10, inputb
= show error message and exit otherwise
ERRORHANDLER NONE
ERROR ERRORMESSAGE
|
|
EXTERN 'cmdname' [, param1,
param2...]
!cmdname [param1, param2...]
Parameters:
cmdname: the name of the external
command to execute
param1/2...: optional
expressions passed to the external command
more...
less...
EXTERN (alias
!) is used to execute commands external to
Tiny Hexer Script. Currently it can be used to activate items of the
Tiny Hexer main menu and to execute functions in Tiny Hexer
plugins.
To execute a main menu entry, prefix the name of the menu command by
'
CMD.'. Some of the commands can make use of additional
parameters (like a filename for the
CMD.FileOpen command).
List of menu commands and their
parameters
To execute a function in a plugin, use the
EXTERN 'PLUGIN'... or
!PLUGIN... syntax.
(See the sources of "exporter.ths" in the Plugin SDK for details).
Menu command execution samples:
= open a file in Tiny Hexer
EXTERN "CMD.FileOpen", 'c:\cmldr'
= alternative
!CMD.FileOpen 'c:\boot.ini'
= open a new editor window
!CMD.FileNew
Plugin execution sample:
= this is an excerpt from the html export script in scripts\export\ex-html.mps
= ...
= call the plugin (located in the tiny hexer root directory)
!PLUGIN (ENVPARSE('%apppath%')+"\\exporter.ths"), "HTML", '::current', outfn, start, amount
|
|
FILECLOSE file
more...
less...
The FILECLOSE command is used to close a file previously opened
by FILEOPEN.
Sample:
VAR f FILE, line TEXT
LET f = FILEOPEN('c:\autoexec.bat', 'r')
= opens the file c:\autoexec.bat for reading
FILEREADTEXTLINE f, line
= reads a line of text from the file
FILECLOSE f
= closes the file handle
MSGBOX ("Line: "+line)
= displays the line
FILEDELETE filename [, flags]
more...
less...
Use the FILEDELETE command to delete the file filename.
The optional flags parameter tells
Tiny Hexer Script whether it should raise an error if the file to be
deleted does not exist or cannot be deleted. If bit 0 (= value 1) of
the flags parameter is not set, an
error is raised if the file does not exist. If bit 1 (= value 2) is not
set, an error is raised if the file cannot be deleted. Set flags to 3 to suppress all errors, set it to 0
(default) to check both conditions.
Sample:
= tries to delete the file, an error is raised if the file does not exist or cannot be deleted
FILEDELETE 'c:\test.tmp'
= tries to delete the file, don't care if the file does exist or can be deleted
FILEDELETE 'c:\test.tmp', 3
FILEREAD file,
buffer [, count]
more...
less...
Use the FILEREAD command to read data from the file file into the variable buffer.
The optional count parameter tells
Tiny Hexer Script how many bytes of data are to be read. If this
parameter is omitted, the type of buffer defines the amount of data to be read
(BYTE, CHAR: 1 Byte, WORD: 2 Bytes, LONGWORD: 4 Bytes, SIGQWORD: 8
Bytes, TEXT: reads from the file until EOF or a 0x00 byte is
found).
If less data than expected has been read from the file, an error is
raised. To avoid those errors (or if the exact amount of data that
should be read from the file is unknown), use the FILEREAD() function
instead of the command.
Sample:
VAR f FILE, wholedata TEXT
LET f = FILEOPEN('c:\autoexec.bat', 'r')
= opens the file c:\autoexec.bat for reading
FILEREAD f, wholedata
= reads all text from the file (only if no 0x00 byte is in the file)
FILECLOSE f
= closes the file handle
MSGBOX ("Contents: "+wholedata)
= displays the contents
|
|
FILEREADBE file, buffer
Parameters:
file: a
variable of type
FILE
buffer: a
variable of type TEXT, CHAR, BYTE, WORD, LONGWORD or
SIGQWORD
more...
less...
Use the FILEREADBE command to read data from the file
file into the variable buffer if the file's contents are stored in BIG
ENDIAN format (e.g. on Motorola CPUs).
The type of buffer defines the amount
of data to be read (BYTE, CHAR: 1 Byte, WORD: 2 Bytes, LONGWORD: 4
Bytes, SIGQWORD: 8 Bytes, TEXT: reads from the file until EOF or a 0x00
byte is found).
If buffer is of type WORD, LONGWORD or
SIGQWORD, the data is swapped after reading (e.g. LONGWORD = Byte 0
becomes Byte 3, Byte 1 becomes Byte 2, Byte 2 becomes Byte 1 and Byte 3
becomes Byte 0). On other data types, the command is similar to the
FILEREAD command (except for the missing count parameter).
If less data than expected has been read from the file, an error is
raised. To avoid those errors (or if the exact amount of data that
should be read from the file is unknown), use the FILEREADBE() function
instead of the command.
|
|
FILEREADTEXTLINE file, txtbuffer [,
breakonwhitespace]
more...
less...
Use the FILEREADTEXTLINE command to read one line of text data
from the file file into the text
variable txtbuffer.
The end of a line is marked using 0x0a, 0x0d, 0x0a+0x0d or 0x0d+0x0a
characters. Those line separators are cut off from txtbuffer.
If the optional parameter breakonwhitespace is set to 1, all
characters less than 0x20 act as line separators. Those line separators
are cut off from txtbuffer.
Sample:
VAR f FILE, line TEXT
LET f = FILEOPEN('c:\autoexec.bat', 'r')
= opens the file c:\autoexec.bat for reading
FILEREADTEXTLINE f, line
= reads a line of text from the file
FILECLOSE f
= closes the file handle
MSGBOX ("Line: "+line)
= displays the line
FILESEEK file,
position [, origin]
more...
less...
Use the FILESEEK command to move the position pointer of file
file to position position manually. FILEREAD... and FILEWRITE
automatically adjust a file's position pointer to the following byte.
Using FILESEEK you can randomly acces data in a file.
If the optional parameter origin is
present, the way of calculating the new position changes. Setting
origin to 0 (= FILE_BEGIN) sets the
position pointer of the file to the absolute value position (default). Setting it to 1 (=
FILE_CURRENT) adds the value of position to the current position. Setting it to 2
(= FILE_END) set the file's position pointer to the value of
position + the file's size.
Sample:
VAR f FILE, line TEXT, fpos LONGWORD, fname TEXT
LET fname = 'c:\dttest.txt'
IF FILEEXISTS(fname)
= open the file for reading and writing
LET f = FILEOPEN(fname, 'rw')
ELSE
= create the file
LET f = FILEOPEN(fname, 'c')
ENDIF
= get current date and time
LET line = ENVPARSE('%date% - %time%')
= set the file pointer to the file's end
FILESEEK f, 0, 2
= append date/time string to the file
FILEWRITE f, (line+"\r\n")
FILECLOSE f
= closes the file handle
|
|
FILESETPROP file, property,
value
more...
less...
FILESETPROP is used to change a special
file's properties. To set a
file's properties, it must have been opened with
read-write access.
property is the
name of the property to be modified,
value is the property's new value. The type of
value depends on the property.
List of available properties
Sample:
VAR newed FILE
= open a new editor window
LET newed = FILEOPEN('::new', 'c')
= set bytes per row property to 12
FILESETPROP newed, 'BytesPerRow', 12
= close the file
FILECLOSE newed
FILEWRITE file, data1 [,
data2...]
Parameters:
file: a
variable of type
FILE
data1/2...:
expressions of type TEXT, CHAR, BYTE, WORD, LONGWORD
or SIGQWORD
more...
less...
Use the FILEWRITE command to write the contents of data1/2... to the file file.
The type of the data... expressions
define the amount of data to be written to the file (BYTE, CHAR: 1
Byte, WORD: 2 Bytes, LONGWORD: 4 Bytes, SIGQWORD: 8 Bytes, TEXT: length
of the text value).
If less data than expected has been written to the file, an error is
raised. To avoid those errors, use the FILEWRITE() function instead of
the command.
Sample:
VAR f FILE, line TEXT, fpos LONGWORD, fname TEXT
LET fname = 'c:\test.txt'
= enter a line of text
LET line = INPUT('Enter a line of text')
= create the file
LET f = FILEOPEN(fname, 'c')
= write line to the file
FILEWRITE f, (line+"\r\n")
FILECLOSE f
= closes the file handle
FILEWRITEBE file, data1 [,
data2...]
Parameters:
file: a
variable of type
FILE
data1/2...:
expressions of type TEXT, CHAR, BYTE, WORD, LONGWORD
or SIGQWORD
more...
less...
Use the FILEWRITEBE command to write the contents of
data1/2... to the file file if the file's contents should be stored in
BIG ENDIAN format (e.g. on Motorola CPUs).
The type of the data... expressions
define the amount of data to be written to the file (BYTE, CHAR: 1
Byte, WORD: 2 Bytes, LONGWORD: 4 Bytes, SIGQWORD: 8 Bytes, TEXT: length
of the text value).
If data... is of type WORD, LONGWORD
or SIGQWORD, the data is swapped before writing (e.g. LONGWORD = Byte 0
becomes Byte 3, Byte 1 becomes Byte 2, Byte 2 becomes Byte 1 and Byte 3
becomes Byte 0). On other data types, the function is similar to the
FILEWRITEBE() function.
If less data than expected has been written to the file, an error is
raised. To avoid those errors, use the FILEWRITEBE() function instead
of the command.
GOTO target
Parameters:
target: name of a
label in the current script
more...
less...
GOTO continues script execution at the position marked with the
label target.
Contrary to the CALL command, GOTO doesn't store the current script
position before going to the marked command, so the RETURN command
cannot be used to return from the subroutine.
GOTO cannot not be used in
LOCAL subroutines to
leave the local scope.
Sample:
= goto the end of the script
GOTO end_of_script
= the following command is never executed
MSGBOX "This message will never be shown"
LABEL end_of_script
END
IF condition :
ifblock [ : ELSE
: elseblock] : ENDIF
Parameters:
condition: a
numeric expression
ifblock,
elseblock: a sequence of Tiny Hexer Script commands
more...
less...
IF... commands are used to execute a sequence of commands
(ifblock) only if the numeric
expression condition equals to a value
other than 0.
If the optional ELSE branch is present, the elseblock command sequence is executed
otherwise.
The ENDIF statement terminates the ifblock or the elseblock sequence.
Sample:
= decimal number to text
LET NUMBER_RADIX = 10
LET NUMBER_PREFIX = ''
LET NUMBER_SUFFIX = ''
MSGBOX "Guess a number game", 64
VAR number BYTE, entered BYTE
LABEL start
= randomly choose a number between 1 and 10
LET number = RANDOM(10)+1
LABEL loop
LET entered = BYTE(INPUT('Enter a number between 1 and 10'))
IF entered == number
MSGBOX 'Right!'
ELSE
IF number < entered
MSGBOX ('My number is less than '+TEXT(entered))
ELSE
MSGBOX ('My number is greater than '+TEXT(entered))
ENDIF
GOTO loop
ENDIF
GOTO start
IFGOTO srcexpr,
expr1, target1 [ , expr2,
target2...]
Parameters:
srcexpr,
expr1,
expr2...:
expressions
target1,
target2...:
labels in the
current script
more...
less...
The IFGOTO command checks whether the value of one of the
expressions expr1, expr2... is equal to the source expression
srcexpr. if a match is found, the
script is continued at the corresponding label (target1, target2...).
Sample:
VAR a byte
a = LONGWORD(INPUT('Enter a number between 1 and 5'))
IFGOTO a, 1, label1, 2, label2, 3, label3, 4, label4, 5, label5
= none of the allowed numbers has been entered, bail
ERROR 'Wrong number entered!'
VAR t TEXT
= make text from number
@@label1:t = 'one':GOTO labelout
@@label2:t = 'two':GOTO labelout
@@label3:t = 'three':GOTO labelout
@@label4:t = 'four':GOTO labelout
@@label5:t = 'five'
= output text number
@@labelout
MSGBOX t
INC numvar [,
numexpr]
Parameters:
numvar: the name of a numeric
variable (CHAR, BYTE, WORD, LONGWORD, SIGQWORD)
numexpr: optional numeric
expression
more...
less...
INC adds the value of the numeric expression numexpr (defaults to 1 if not specified) to the
value already stored in the numeric variable numvar. (Note: The INC command is faster
than the numeric '+' operator.)
Sample:
VAR number LONGWORD
= variable number is set to the value 10
LET number = 10
INC number, 20
= variable number now contains the value 30.
INCLUDE 'filename'
Parameters:
filename: filename of the script to be
included
more...
less...
The INCLUDE preprocessor statement is similar to #include in the
C programming language. It is used to replace itself by the contents of
another script file. The syntax is very strict: The INCLUDE command
must be the only command in a script line, the filename must be written literally in single
quotes and between the INCLUDE statement and the first quote must be
exactly one blank character. If the filename does not contain a path,
the standard include path (<tiny hexer application
path>\scripts\inc) is searched for the given filename.
As of version 1.6.0.2 of Tiny Hexer the filename may be abbreviated: an
asterisk is replaced by the filename of the current script, not
including path and file extension (e.g. if you want to include a file
called "script.inc" in a script called "script.mps", you
can write INCLUDE '*.inc')
Sample:
= include the standard definitions in def.mps
INCLUDE 'def.mps'
= show a warning message box
= MB_ICONWARNING is defined in def.mps
MSGBOX 'Warning!', MB_ICONWARNING
|
|
INIWRITE filename, section
[, key [,value]]
more...
less...
Use the INIWRITE command to write data to ini-style text
files.
filename is the name of the ini
file.
section is the name of the section in
the ini file ([section] lines).
key is the name of the key in the ini
file (the part to the left of the equal sign).
value is the data of the key (the part
to the right of the equal sign).
If key and value are omitted, the whole section section is removed from the ini file.
If value is omitted, key is removed from section section in the ini file.
Sample:
DEF ini "c:\\mpthtest.ini"
= write some values to the ini file
iniwrite ini, "section 1", "key 1", 2
iniwrite ini, "section 1", "key 2", "abc"
iniwrite ini, "section 2", "key 1", 2
iniwrite ini, "section 2", "key 2", "abc"
= remove section 2 from the ini file
iniwrite ini, "section 2"
= remove section 1/key 2 from the ini file
iniwrite ini, "section 1", "key 2"
VAR val LONGWORD
= try to read the section 1/key 1
IF INIREAD(ini, "section 1", "key 1", @val)
MSGBOX ('Value of section 1/key 1: '+TEXT(val))
ELSE
ERROR ('Cannot read section 1/key 1 value from '+ini)
ENDIF
|
|
LABEL name
@@name
Parameters:
name: name of the label
more...
less...
The
LABEL statement (alias
@@) marks the following
command with the identifier
name, so
the CALL, GOTO and LOOP commands and CALL() function can "jump" to this
position. (
Note: As of version 1.7 of Tiny Hexer, you may and
should use
LOCAL...ENDLOCAL constructs to define
subroutines.)
Sample:
INCLUDE 'def.mps'
MSGBOX "To stop this script, press the 'Alt' key", MB_ICONINFORMATION
= mark the first command with 'start'
LABEL start
= infinite loop
GOTO start
= alternate syntax
@@start1
= infinite loop
GOTO start1
LET var =
expr
var = expr
more...
less...
The LET command is used to assign the value of expression
expr to the variable var. This assignment succeeds only if the data
types of var and expr are compatible.
Variables must be defined using the VAR command before data can be
assigned to them.
In unambigous cases, the LET keyword may be omitted.
Sample:
= define some variables
VAR t1 TEXT, c1 CHAR, b1 BYTE, d1 LONGWORD
= success
LET t1 = c1
c1 = t1
b1 = d1
LET d1 = b1
= because the CHAR type is compatible to numeric and text data types,
= the following assignments also will succeed
LET b1 = c1
LET c1 = d1
= to assign incompatible data types, use the conversion functions
LET t1 = TEXT(b1)
LET t1 = '0':LET d1 = LONGWORD(t1)
= these assignments will fail
LET t1 = b1
LET d1 = t1
LOCAL name :
block : ENDLOCAL
Parameters:
name: name of the subroutine (label
name)
block: a sequence of Tiny Hexer Script
commands
more...
less...
LOCAL...ENDLOCAL constructs are used to define subroutines. They
can be put anywhere in a Tiny Hexer Script, normal script operation
does not execute such blocks until they are explicitly called by using
the CALL or LOOP commands or the CALL() function.
You may redefine variables in local blocks, then they become local to
that block, i.e. they do not inherit the value (and type) of an equally
named global variable.
LOCAL...ENDLOCAL blocks cannot be nested. The RETURN command can be
used to send a value back to a CALL() function.
Sample:
= this script shows the difference between a call to a LABEL
= and a call to a LOCAL block
= don't use global variables, so CALL <LABEL> (= #<LABEL>) make
= them locally as CALL <LOCAL> (= #<LOCAL>) does, but there
= are still differences
OPTION GLOBALVARS, 0
= predefine global variables
VAR t1 TEXT t2 TEXT
LET t1 = "a"
LET t2 = "b"
= you must skip over a label block to avoid running into it
GOTO start
= normal sub routine
= aka @@label_block
LABEL label_block
VAR cnt BYTE:= global variable!
POP cnt
POP t1
CONCAT t1, t2:= t2 is a local copy of the global variable and thus it does
= inherit the global value "b"
= two iterations
IF (cnt == 2): CONCAT t1, #label_block(t1,1): ENDIF
= end the label block and return
RETURN t1
@@start
= local blocks can be put anywhere in a script, they are not executed during
= normal script operation
LOCAL local_block
= redefine variables, so changes become local
VAR t1 TEXT t2 TEXT cnt BYTE:= local variables!
POP cnt
POP t1
CONCAT t1, t2:= t2 is a totally local variable and does not inherit
= the global value, so it is empty
= two iterations
IF (cnt == 2): CONCAT t1, #local_block(t1,1): ENDIF
= end the label block and return
RETURN t1
= end the local block
ENDLOCAL
= the script is continued after an ENDLOCAL during normal operation
VAR output TEXT:= output for textbox
CONCAT output, "LOCAL result: "+#local_block(t1,2)+"\n"
CONCAT output, "LABEL result: "+#label_block(t1,2)+"\n"
TEXTBOX output
|
|
LOOP target,
count
more...
less...
LOOP calls the subroutine marked with the label target count
times. During subroutine execution, the current loop index can be
retrieved by reading the special variable LOOP.
Contrary to the CALL command, no additional parameters can be passed to
the subroutine. Use the PUSH command to store parameters on the stack.
Sample:
= factorial function
INCLUDE 'def.mps'
OPTION GLOBALVARS, 1
LET NUMBER_RADIX = 10
LET NUMBER_PREFIX = ''
LET NUMBER_SUFFIX = ''
VAR b BYTE
VAR res SIGQWORD
LABEL start
LET b = BYTE(INPUT('Factorial function', 'Enter a number between 1 and 20'))
IF (b < 1) OR (b > 20): GOTO start: ENDIF
LET res = 0
LOOP factorial, (b+1)
MSGBOX ('!'+TEXT(b)+' = '+TEXT(res)), MB_ICONASTERISK, 'Factorial function'
END
LABEL factorial
IF loop == 0
LET res = 1
ELSE
LET res = res * loop
ENDIF
RETURN
MSGBOX message [,
flags [, title]]
more...
less...
MSGBOX shows a dialog displaying the text
message.
The optional
flags parameter tells
Windows to change the behaviour and/or appearance of the dialog (see
MSGBOX
flags). If you want to show a
message box containing more than one button, you should use the
MSGBOX() function to retrieve the button clicked by the user.
The optional
title parameter modifies
the title bar caption of the message dialog.
Sample:
INCLUDE 'def.mps'
= show an info message
MSGBOX 'Info message', MB_ICONINFORMATION
= show a warning message using a different title
MSGBOX 'Warning message', MB_ICONWARNING, 'Warning title'
= show an error message with 'yes' and 'no' buttons
MSGBOX 'Error message', (MB_ICONERROR OR MB_YESNO)
POP var
more...
less...
POP returns a data stored on the stack and assigns it to the
variable var. The data is removed from
the stack. The data type depends on the data on the stack and can be
retrieved using the TYPEOFSTACK special variable. Data can be pushed to
the stack using the CALL and PUSH commands and the CALL()
function.
In Tiny Hexer Script, the stack is a LIFO (last in first out), so when
pushing the text "A" first and after this the numeric value 200 to the
stack, POP returns 200 on the first and "A" on the second call. The
stack can hold up to 4095 data values at a time.
Sample:
VAR t1 TEXT, t2 TEXT
= pushes 'first', than 'second' to the stack and calls the label concat
CALL concat, "first", "second"
= use the END command to avoid running into the subroutine again
END
LABEL concat
POP t1
= t1 now contains 'second' (the last parameter pushed to the stack)
POP t2
= t2 now contains 'first' (the last-but-one parameter pushed to the stack)
= displays the message 'second first' !!!
MSGBOX t1+" "+t2
= return from the subroutine
RETURN
|
|
PUSH param1 [,
param2...]
more...
less...
PUSH stores all its parameters param1/2... to the stack. To restore data pushed
to the stack, use the POP command.
In Tiny Hexer Script, the stack is a LIFO (last in first out), so when
pushing the text "A" first and after this the numeric value 200 to the
stack, POP returns 200 on the first and "A" on the second call. The
stack can hold up to 4095 data values at a time.
Sample:
= exchange vars example
VAR t1 TEXT, t2 TEXT
t1 = 'first'
t2 = 'second'
= now exchange the two variables using the stack as temporary storage
PUSH t1, t2
POP t1
POP t2
= t1 now contains the text 'second', t2 now contains the text 'first'
REGWRITE key [,
name [,value]]
more...
less...
Use the REGWRITE command to write data to the registry.
key is the name of the registry key.
by default, REGWRITE sets values in the HKEY_CURRENT_USER root key. to
select another root key, prefix key by
the name of the root key (e.g.
'HKEY_LOCAL_MACHINE\Software...').
Note: To write data to Tiny Hexer's settings database rather
than to the registry, use the 'HKEY_SETTINGS' pseudo root
key.
name is the name of the value in the
given registry key.
value is the actual data to be stored
in the registry.
If name and value are omitted, the whole key key is removed from the registry.
If value is omitted, the data
name is removed from the key
key in the registry.
Sample:
DEF reg "HKEY_CURRENT_USER\\Temporary Test Key"
= write some data to the registry
regwrite reg, "name1", 2
regwrite reg, "name2", "abc"
VAR val LONGWORD val_t TEXT
= try to read name1 as LONGWORD
IF REGREAD(reg, "name1", @val)
MSGBOX ('Value of name1: '+TEXT(val))
ELSE
ERROR ('Cannot read name1 value from '+reg)
ENDIF
= try to read name2 as text
IF REGREAD(reg, "name2", @val_t)
MSGBOX ('Value of name2: '+val_t)
ELSE
ERROR ('Cannot read name2 value from '+reg)
ENDIF
= delete temporary key
regwrite reg
|
|
REPEAT : block : UNTIL condition
Parameters:
block: a sequence of Tiny Hexer Script
commands
condition: a
numeric expression
more...
less...
REPEAT...UNTIL commands are used to execute a sequence of
commands (block) as long as the
numeric expression condition equals to
0.
Contrary to the WHILE...ENDWHILE command, the block command sequence is always executed at least
once.
Sample:
INCLUDE 'def.mps'
VAR button LONGWORD
= enter the loop
REPEAT
button = MSGBOX('Leave this loop?', MB_YESNO or MB_ICONQUESTION or MB_DEFBUTTON2)
= leave the loop only if the user clicked the IDYES button
UNTIL button == IDYES
RETURN [return_value]
more...
less...
Use the RETURN command to end a subroutine executed by CALL,
CALL() or LOOP and return to the command following the calling.
If the subroutine has been executed by the CALL() function, a value
return_value can be returned to the
calling expression.
Sample:
MSGBOX "Main block"
CALL Sub1
MSGBOX CALL("Sub2")
MSGBOX "Main block again"
END
@@Sub1
MSGBOX "Subroutine 1, called by the CALL command"
RETURN
@@Sub2
RETURN "Subroutine 2, called by the CALL() function"
SHELL program [,
parameters [, show [, directory
[, wait]]]]
more...
less...
The SHELL command is used to execute the external application
program.
Optionally the command line arguments parameters can be passed to program.
Additionally you can tell Tiny Hexer Script to show or hide the
external application using the show
parameter (SW_HIDE, SW_SHOW...)
The optional directory parameter tells
Windows to set program's current
directory.
The optional wait flag tells Tiny
Hexer Script whether to wait until the external program has finished
(1) or not (0, this is the default).
Sample:
= open autoexec.bat in editor in maximized state
INCLUDE 'def.mps'
SHELL 'Notepad.exe', 'c:\autoexec.bat', SW_SHOWMAXIMIZED
SHOWPROGRESS
SHOWPROGRESS percentage
SHOWPROGRESS max, current
more...
less...
The SHOWPROGRESS command is used to control the progress
indicator on the status bar of Tiny Hexer's main window.
SHOWPROGRESS without parameters hides the progress
indicator.
SHOWPROGRESS percentage sets
the progress indicator to the value percentage (0..100). A value greater than 99 hides
the progress indicator.
SHOWPROGRESS max, current lets Tiny Hexer calculate the percentage
itself. If current is equal to or
greater than max (percentage >=
100), the progress indicator is hidden.
Sample:
= show a progress value of 50 percent
SHOWPROGRESS 50
MSGBOX "50% progress"
= show a progress of 75 percent (150/200 = 0.75)
SHOWPROGRESS 200, 150
MSGBOX "75% progress ((150 / 200) * 100)"
= hide the progress bar
SHOWPROGRESS
TAGVAR var,
[tag_pos], [tag_len]
more...
less...
Use the
TAGVAR command to set, modify or remove tags of
variables. Tagged variables are used in the
Structure Viewer to display hyperlinks in the
browser window.
If either the
tag_pos or the
tag_len parameter is empty, the
corresponding tag part of
var remains
unchanged.
If both
tag_pos and
tag_len are empty,
var is untagged.
Sample:
= TAGVAR example:
=
= display a hyperlink in the browser window that selects the first 7 bytes in the
= current editor
=
= NOTE: This sample script must be loaded into the structure viewer!
VAR browser FILE
= open a file to the browser structview browser window to write the data
browser = FILEOPEN('::browser','c')
VAR hyper TEXT
LET hyper = "Select the first seven bytes in the current editor.\n\n"
= 0: position of link-block
= 7: length of link-block
TAGVAR hyper, 0, 7
FILEWRITE browser, hyper
LET hyper = "This text is not a hyperlink."
= untag the variable
TAGVAR hyper, ,
FILEWRITE browser, hyper
= close the browser file
FILECLOSE browser
|
|
TEXTBOX text [,
title]
more...
less...
The TEXTBOX command is used to display a (multiline)
text in a modal window. This text can
be copied to the clipboard and/or saved to disk.
text is the text to display.
title is the optional caption of the
message window's title bar. If this parameter is omitted, a default
title is used.
Sample:
= TEXTBOX example:
=
= read the directory C:\ via the shell and show the dir list
= using the TEXTBOX command
VAR msg TEXT
IF (SHELL(ENVPARSE('%comspec%'), '/k DIR', 0, 'C:\', @msg) != 0)
ERROR "Cannot execute shell"
ENDIF
TEXTBOX msg, "Directory List"
VAR name
type [, name type...]
Parameters:
name: name of the
variable to be declared
type:
type
of the variable to be declared
more...
less...
The VAR command declares the variable name and tells Tiny Hexer Script its data
type.
variables can be declared only once, they must be declared before other
commands can use them.
Sample:
= declare a text and a number (Byte) variable
VAR msg TEXT, num BYTE
= assign a value
LET msg = 'Hello'
= show message
MSGBOX msg
= the following does not work as num is not of type text
LET num = 'Hello'
WHILE condition :
block : ENDWHILE
Parameters:
condition: a
numeric expression
block: a sequence of Tiny Hexer Script
commands
more...
less...
WHILE...ENDWHILE commands are used to execute a sequence
of commands (block) as long as the
numeric expression condition does not
equal to 0.
Contrary to the REPEAT...UNTIL command, the block command is not executed at all if
condition equals to 0.
Sample:
= the command between WHILE...ENDWHILE will never be executed
WHILE 0 == 1
MSGBOX 'This message will never be shown!'
ENDWHILE
===============================================
VAR num BYTE
LET num = 0
WHILE num != 8
INC num, 1
ENDWHILE
MSGBOX ("Number is: "+TEXT(num))